﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;

namespace WPHttpServer
{
    public class HttpResponse : HttpMessage
    {
        public HttpStatusCode StatusCode { get; private set; }
        public IResponseContentProvider Content { get; set; }

        public HttpResponse(HttpStatusCode statusCode)
            : this(statusCode, null)
        {
            
        }

        public HttpResponse(HttpStatusCode statusCode, IResponseContentProvider content)
        {
            StatusCode = statusCode;
            Content = content;
        }

        internal IEnumerable<byte> CreateResponseMessage()
        {
            StringBuilder headersStringBuilder = new StringBuilder();

            // craft the default headers
            headersStringBuilder.Append("HTTP/1.1 ")
                                .Append((int)StatusCode)
                                .Append(" ")
                                .Append(Enum.GetName(typeof(HttpStatusCode), this.StatusCode))
                                .AppendLine();

            // craft the content
            byte[] contentData = this.Content != null ? this.Content.GetContentData() : new byte[0];

            EnsureRequiredHeaders(contentData.Length);

            foreach (KeyValuePair<string, string> httpHeader in Headers)
            {
                headersStringBuilder.Append(httpHeader.Key)
                                    .Append(": ")
                                    .Append(httpHeader.Value)
                                    .AppendLine();
            }

            headersStringBuilder.AppendLine();

            byte[] headersData = Encoding.UTF8.GetBytes(headersStringBuilder.ToString());            

            return headersData.Concat(contentData);
        }

        private void EnsureRequiredHeaders(int contentLength)
        {
            if (!Headers.ContainsKey(HttpConstants.CONTENT_TYPE_HEADER_NAME) && 
                contentLength > 0 && 
                !string.IsNullOrWhiteSpace(this.Content.ContentMediaTypeName))
            {
                Headers.Add(HttpConstants.CONTENT_TYPE_HEADER_NAME, this.Content.ContentMediaTypeName);
            }

            if (!Headers.ContainsKey(HttpConstants.CONTENT_LENGTH_HEADER_NAME))
            {
                Headers.Add(HttpConstants.CONTENT_LENGTH_HEADER_NAME, contentLength.ToString());
            }

            if (!Headers.ContainsKey(HttpConstants.DATE_HEADER_NAME))
            {
                Headers.Add(HttpConstants.DATE_HEADER_NAME, DateTime.Now.ToUniversalTime().ToString("ddd, d MMM yyyy HH:mm:ss UTC")); 
            }

            if (!Headers.ContainsKey(HttpConstants.CONNECTION_HEADER_NAME))
            {
                Headers.Add(HttpConstants.CONNECTION_HEADER_NAME, "Keep-Alive"); 
            }
        }
    }
}